package com.education.platform.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.education.platform.common.ResultCode;
import com.education.platform.dto.demand.DemandCreateDTO;
import com.education.platform.entity.Demand;
import com.education.platform.exception.BusinessException;
import com.education.platform.mapper.DemandMapper;
import com.education.platform.service.DemandService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 需求服务实现类
 *
 * @author education-platform
 * @since 2024-09-27
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class DemandServiceImpl implements DemandService {

    private final DemandMapper demandMapper;

    @Override
    @Transactional
    public Long createDemand(DemandCreateDTO demandCreateDTO, Long parentId) {
        Demand demand = new Demand();
        demand.setParentId(parentId);
        demand.setTitle(demandCreateDTO.getTitle());
        demand.setContentMd(demandCreateDTO.getContentMd());
        demand.setSubject(demandCreateDTO.getSubject());
        demand.setGrade(demandCreateDTO.getGrade());
        demand.setTeachingType(demandCreateDTO.getTeachingType());
        demand.setBudgetMin(demandCreateDTO.getBudgetMin());
        demand.setBudgetMax(demandCreateDTO.getBudgetMax());
        demand.setAddress(demandCreateDTO.getAddress());
        demand.setRequirements(demandCreateDTO.getRequirements());
        demand.setStatus(Demand.Status.PUBLISHED.name());
        demand.setViewCount(0);
        demand.setReplyCount(0);

        // 处理期望时间（转为JSON）
        if (demandCreateDTO.getPreferredTime() != null && !demandCreateDTO.getPreferredTime().isEmpty()) {
            demand.setPreferredTime(JSONUtil.toJsonStr(demandCreateDTO.getPreferredTime()));
        }

        // 处理附件（转为JSON）
        if (demandCreateDTO.getAttachments() != null && !demandCreateDTO.getAttachments().isEmpty()) {
            demand.setAttachments(JSONUtil.toJsonStr(demandCreateDTO.getAttachments()));
        }

        // 设置过期时间，默认30天
        LocalDateTime expiresAt = demandCreateDTO.getExpiresAt();
        if (expiresAt == null) {
            expiresAt = LocalDateTime.now().plusDays(30);
        }
        demand.setExpiresAt(expiresAt);

        demandMapper.insert(demand);
        return demand.getId();
    }

    @Override
    @Transactional
    public void updateDemand(Long id, DemandCreateDTO demandCreateDTO, Long parentId) {
        Demand demand = getDemandById(id);

        // 验证权限
        if (!demand.getParentId().equals(parentId)) {
            throw new BusinessException(ResultCode.FORBIDDEN);
        }

        // 只有已发布状态的需求才能修改
        if (!Demand.Status.PUBLISHED.name().equals(demand.getStatus())) {
            throw new BusinessException(ResultCode.CURRENT_STATUS_ERROR);
        }

        demand.setTitle(demandCreateDTO.getTitle());
        demand.setContentMd(demandCreateDTO.getContentMd());
        demand.setSubject(demandCreateDTO.getSubject());
        demand.setGrade(demandCreateDTO.getGrade());
        demand.setTeachingType(demandCreateDTO.getTeachingType());
        demand.setBudgetMin(demandCreateDTO.getBudgetMin());
        demand.setBudgetMax(demandCreateDTO.getBudgetMax());
        demand.setAddress(demandCreateDTO.getAddress());
        demand.setRequirements(demandCreateDTO.getRequirements());

        // 处理期望时间
        if (demandCreateDTO.getPreferredTime() != null && !demandCreateDTO.getPreferredTime().isEmpty()) {
            demand.setPreferredTime(JSONUtil.toJsonStr(demandCreateDTO.getPreferredTime()));
        }

        // 处理附件
        if (demandCreateDTO.getAttachments() != null && !demandCreateDTO.getAttachments().isEmpty()) {
            demand.setAttachments(JSONUtil.toJsonStr(demandCreateDTO.getAttachments()));
        }

        if (demandCreateDTO.getExpiresAt() != null) {
            demand.setExpiresAt(demandCreateDTO.getExpiresAt());
        }

        demandMapper.updateById(demand);
    }

    @Override
    @Transactional
    public void deleteDemand(Long id, Long parentId) {
        Demand demand = getDemandById(id);

        // 验证权限
        if (!demand.getParentId().equals(parentId)) {
            throw new BusinessException(ResultCode.FORBIDDEN);
        }

        demandMapper.deleteById(id);
    }

    @Override
    public Demand getDemandById(Long id) {
        Demand demand = demandMapper.selectById(id);
        if (demand == null) {
            throw new BusinessException(ResultCode.NOT_FOUND);
        }
        return demand;
    }

    @Override
    public IPage<Demand> getDemandPage(Page<Demand> page, String subject, String grade,
                                      String teachingType, String status) {
        return demandMapper.selectDemandPageWithUser(page, subject, grade, teachingType, status);
    }

    @Override
    public List<Demand> getDemandsByParentId(Long parentId) {
        return demandMapper.selectByParentId(parentId);
    }

    @Override
    public void incrementViewCount(Long id) {
        demandMapper.incrementViewCount(id);
    }

    @Override
    @Transactional
    public void closeDemand(Long id, Long parentId) {
        Demand demand = getDemandById(id);

        // 验证权限
        if (!demand.getParentId().equals(parentId)) {
            throw new BusinessException(ResultCode.FORBIDDEN);
        }

        demand.setStatus(Demand.Status.CLOSED.name());
        demandMapper.updateById(demand);
    }

    @Override
    public List<Demand> getHotDemands(Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        return demandMapper.selectHotDemands(limit);
    }

    @Override
    public List<Demand> getExpiringDemands() {
        return demandMapper.selectExpiringDemands();
    }

    @Override
    @Transactional
    public void autoCloseExpiredDemands() {
        LambdaQueryWrapper<Demand> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Demand::getStatus, Demand.Status.PUBLISHED.name())
               .lt(Demand::getExpiresAt, LocalDateTime.now());

        List<Demand> expiredDemands = demandMapper.selectList(wrapper);

        for (Demand demand : expiredDemands) {
            demand.setStatus(Demand.Status.EXPIRED.name());
            demandMapper.updateById(demand);
        }

        log.info("自动关闭过期需求数量: {}", expiredDemands.size());
    }
}
